<?php
/**
 * 让客户端以统一的方式处理各个对象
 * Class Composite
 */

// 通过接口定义对象行为。不同对象的行为不同。客户端调用时，依赖接口即可

interface Employee
{
    public function __construct(string $name, float $salary);

    public function getName(): string;

    public function setSalary(float $salary);

    public function getSalary(): float;

    public function getRoles(): array;
}

class Developer implements Employee
{
    protected $salary;
    protected $name;
    protected $roles;

    public function __construct(string $name, float $salary)
    {
        $this->name = $name;
        $this->salary = $salary;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getSalary(): float
    {
        return $this->salary;
    }

    public function setSalary(float $salary): float
    {
        $this->salary = $salary;
    }

    public function getRoles(): array
    {
        return $this->roles ?: [];
    }
}

class Designer implements Employee
{
    protected $name;
    protected $salary;
    protected $roles;

    public function __construct(string $name, float $salary)
    {
        $this->name = $name;
        $this->salary = $salary;
    }

    public function setSalary(float $salary)
    {
        $this->salary = $salary;
    }

    public function getSalary(): float
    {
        return $this->salary;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getRoles(): array
    {
        return $this->roles;
    }
}

// 机构，包括不同类型的员工
class Organization
{
    protected $employees;

    public function addEmployee(Employee $employee)
    {
        $this->employees[] = $employee;
    }

    public function getNetSalaries(): float
    {
        $netSalary = 0;
        foreach ($this->employees as $employee) {
            $netSalary += $employee->getSalary();
        }
        return $netSalary;
    }
}


// usage
$john = new Developer('Jonh Doe', 12000);
$jane = new Designer('Jane Doe', 15000);

$organiation = new Organization();
$organiation->addEmployee($john);
$organiation->addEmployee($jane);

echo "net salaries: " . $organiation->getNetSalaries();
